﻿using System;

namespace masterview.Code.db
{
    public class SqlConnectionString
    {      
        private const string True = "True";
        private const string False = "Flase";
        private const string SqlConnectionStringTemplate5 = "Data Source={0};Initial Catalog={1};Persist Security Info={2};User ID={3};Password={4}";
        private const string SqlConnectionStringTemplate7 = "Data Source={0};Initial Catalog={1};Persist Security Info={2};User ID={3};Password={4};Max Pool Size={5};Connect Timeout ={6}";

        /// <summary>
        /// Construct an instance
        /// </summary>
        /// <param name="dataSource">defines Data Source</param>
        /// <param name="initialCatalog">defines Initial Catalog</param>
        /// <param name="persistSecurityInfo">defines Persist Security Info</param>
        /// <param name="userID">defines User ID</param>
        /// <param name="password">defines Password</param>
        public SqlConnectionString(string dataSource, string initialCatalog, bool persistSecurityInfo, string userID, string password)
        {
            DataSource = dataSource;
            InitialCatalog = initialCatalog;
            PersistSecurityInfo = persistSecurityInfo;
            UserID = userID;
            Password = password;
            MaxPoolSize = null;
            ConnectTimeout = null;
        }

        /// <summary>
        /// Construct an instance
        /// </summary>
        /// <param name="dataSource">defines Data Source</param>
        /// <param name="initialCatalog">defines Initial Catalog</param>
        /// <param name="persistSecurityInfo">defines Persist Security Info</param>
        /// <param name="userID">defines User ID</param>
        /// <param name="password">defines Password</param>
        /// <param name="maxPoolSize">defines Max Pool Size</param>
        /// <param name="connectTimeout">defines Connect Timeout</param>
        public SqlConnectionString(string dataSource, string initialCatalog, bool persistSecurityInfo, string userID, string password, string maxPoolSize, string connectTimeout)
        {
            DataSource = dataSource;
            InitialCatalog = initialCatalog;
            PersistSecurityInfo = persistSecurityInfo;
            UserID = userID;
            Password = password;
            MaxPoolSize = maxPoolSize;
            ConnectTimeout = connectTimeout;
        }

        public string DataSource { get; set; }

        public string InitialCatalog { get; set; }

        public bool PersistSecurityInfo { get; set; }

        public string UserID { get; set; }

        public string Password { get; set; }

        public string MaxPoolSize { get; set; }

        public string ConnectTimeout { get; set; }

        public override string ToString()
        {
            // 7 params
            if (!String.IsNullOrEmpty(DataSource) && !String.IsNullOrEmpty(InitialCatalog) && !String.IsNullOrEmpty(UserID) && !String.IsNullOrEmpty(Password) && !String.IsNullOrEmpty(MaxPoolSize) && !String.IsNullOrEmpty(ConnectTimeout))
            {
                return String.Format(SqlConnectionStringTemplate7, DataSource, InitialCatalog, PersistSecurityInfo ? True : False, UserID, Password, MaxPoolSize, ConnectTimeout);
            }
            // 5 params
            if (!String.IsNullOrEmpty(DataSource) && !String.IsNullOrEmpty(InitialCatalog) && !String.IsNullOrEmpty(UserID) && !String.IsNullOrEmpty(Password))
            {
                return String.Format(SqlConnectionStringTemplate5, DataSource, InitialCatalog, PersistSecurityInfo ? True : False, UserID, Password);
            }
            return String.Empty;
        }

        public void Parse(string connectionString)
        {
            if (String.IsNullOrWhiteSpace(connectionString)) return;
            DataSource = ParseDataSource(connectionString);
            InitialCatalog = ParseInitialCatalog(connectionString);
            PersistSecurityInfo = ParsePersistSecurityInfo(connectionString).Equals(True);
            UserID = ParseUserID(connectionString);
            Password = ParsePassword(connectionString);
            MaxPoolSize = ParseMaxPoolSize(connectionString);
            ConnectTimeout = ParseConnectTimeout(connectionString);
        }

        /// <summary>
        /// Returns SqlConnectionString instance
        /// </summary>
        /// <returns>SqlConnectionString instance</returns>
        public SqlConnectionString GetInstance()
        {
            return new SqlConnectionString(DataSource, InitialCatalog, PersistSecurityInfo, UserID, Password,
                                                MaxPoolSize, ConnectTimeout);
        }

        /// <summary>
        /// Parses string and returns SqlConnectionString instance
        /// </summary>
        /// <param name="connectionString">defines string to parse parameters</param>
        /// <returns>SqlConnectionString instance</returns>
        public SqlConnectionString GetInstance(string connectionString)
        {
            Parse(connectionString);
            return new SqlConnectionString(DataSource, InitialCatalog, PersistSecurityInfo, UserID, Password,
                                                MaxPoolSize, ConnectTimeout);
        }

        private static string ParseValue(string key, string source)
        {
            if (source.IndexOf(key) < 0) return null;
            var startIndex = source.IndexOf(key) + key.Length;
            var value = source.Substring(startIndex);
            return value.IndexOf(";") > 0 ? value.Substring(0, value.IndexOf(";")) : value;
        }

        private static string ParseDataSource(string connectionString)
        {
            const string key = "Data Source=";
            return ParseValue(key, connectionString);
        }

        private static string ParseInitialCatalog(string connectionString)
        {
            const string key = "Initial Catalog=";
            return ParseValue(key, connectionString);
        }

        private static string ParsePersistSecurityInfo(string connectionString)
        {
            const string key = "Persist Security Info=";
            return ParseValue(key, connectionString);
        }

        private static string ParseUserID(string connectionString)
        {
            const string key = "User ID=";
            return ParseValue(key, connectionString);
        }

        private static string ParsePassword(string connectionString)
        {
            const string key = "Password=";
            return ParseValue(key, connectionString);
        }

        private static string ParseMaxPoolSize(string connectionString)
        {
            const string key = "Max Pool Size=";
            return ParseValue(key, connectionString);
        }

        private static string ParseConnectTimeout(string connectionString)
        {
            const string key = "Connect Timeout =";
            return ParseValue(key, connectionString);
        }
    }
}